package org.gthelper.server;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.sql.Timestamp;

//import org.apache.commons.net.ntp.TimeStamp;
import org.gthelper.error.ErrorCode;
import org.gthelper.order.Header;
import org.gthelper.order.OrderInfo;
import org.gthelper.data.DataGeter;
import org.gthelper.database.UserInfo;
import org.gthelper.database.UserinfoStatus;
import org.gthelper.security.IchkID;
//import org.gthelper.testtools.Printer;

/**
 * 消息预处理
 * @author pig
 * 从流中取出命令，若是带签名的命令，则验证其签名
 */
public class MsgPretreater
{
	public int order = -1;
	public String id;
	public byte[] data;
	public byte[] sign;
	
	/**
	 * 预处理客户端请求
	 * @param orderinfo 
	 * @param chker 实现IchkID接口的加密和验证类
	 * @return	ERRORCODE
	 * 			数据流格式错误：WRONGFORM
	 * 			用户执行非登录、注册操作时签名错误：SIGNWRONG
	 * 			用户执行非登录、注册操作但未登录：NOTLOGIN
	 * 			用户执行非登录、注册操作但超过登录有效时间：LOGINTIMEOUT
	 * 			正常：NORMAL
	 * @throws IOException
	 */
	public int treat(OrderInfo orderinfo,IchkID chker) throws IOException
	{
		DataInputStream dis = new DataInputStream(orderinfo.mainInput);
		
			//get order number
			long llength = dis.readLong();
			if(llength!=4)return ErrorCode.WRONGFORM;
			int iorder = dis.readInt();
			if(iorder==-1)return ErrorCode.WRONGFORM;
			order = iorder;
//			Printer.print("msg-order", order);
			//get data
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			DataGeter dg = new DataGeter();
			int c=dg.getData(dis, baos);
			if(c!=ErrorCode.NORMAL)return c;
			data = baos.toByteArray();
			baos.reset();
			baos.close();
			
			//获取ID
			long idlength = 0;
			for(int i=0;i<8;i++)
			{
				if(data[i]!='\0')
				{
					long tmp = data[i];
					tmp = tmp << (8*(7-i));
					idlength = idlength+tmp;
				}
			}
			
			byte[] usrID = new byte[(int)idlength];
			for(int i=0;i<idlength;i++)
			{
				usrID[i]=data[8+i];
			}
			id = new String(usrID,"UTF-8");
			orderinfo.userID = id;
			
			
			
			//这四种情况是没有签名的，要除去。
			if((this.order!=Header.OD_ASKREG)&&(this.order!=Header.OD_ASKFORLOGIN)&&(this.order!=Header.OD_LOGIN)&&(this.order!=Header.OD_REG))
			{
				//get sign data
				baos = new ByteArrayOutputStream();
				c=dg.getData(dis, baos);
				if(c!=ErrorCode.NORMAL)return c;
				sign = baos.toByteArray();
				baos.reset();
				baos.close();
				
				
				//check identity
				UserInfo userinfo=null;
				try {
					userinfo = UserInfo.getUserInfobyID(id);
				} catch (Exception e2) {
					// TODO 自动生成的 catch 块
					e2.printStackTrace();
					return ErrorCode.DATABASEERR;
				}
				if(userinfo==null)return ErrorCode.IDNOTEXIST;
				
				//验证登录状态
				int islogin = isLogin(userinfo);
				if(ErrorCode.NORMAL!=islogin)return islogin;
				
				//get user publickey
				byte[] publickey;
				try {
					publickey = IchkID.decryptBASE64(userinfo.getpublickey_user());
					if(publickey.length<10)return ErrorCode.NONPUBKEY;
				} catch (Exception e1) {
					// TODO 自动生成的 catch 块
					e1.printStackTrace();
					return ErrorCode.DATABASEERR;
				}
				
				try {
					//check sign
					if(chker.chkSign(data, sign, publickey))
					{
						orderinfo.order = order;
						orderinfo.setOrderStream(data);
						userinfo.setlastcalltime(new Timestamp(System.currentTimeMillis()));
						userinfo.UpdateUserInfo();
						return ErrorCode.NORMAL;
					}
					else{
						return ErrorCode.WRONGSIGN;
					}
					
				} catch (Exception e) {
					// TODO 自动生成的 catch 块
					return ErrorCode.WRONGSIGN;
				}
				
			}
			
		
		//到达此处，可以赋值了
		orderinfo.order = order;
		orderinfo.setOrderStream(data);
		return ErrorCode.NORMAL;
		
	}
	
	
	/**
	 * 验证用户登录状态
	 * @param id：用户ID
	 * @return：用户登录状态/
	 * 			已登录且在登录有效时间内:NORMAL
	 * 			已登录但已超过有效时间:LOGINTIMEOUT
	 * 			已登录且登录状态有效:NORMAL
	 */
	private int isLogin(UserInfo userinfo) {
		// TODO 自动生成的方法存根
		//数据库完成后添加
		//返回id登录状态
		if(userinfo.getstatus_login()!=UserinfoStatus.Login)return ErrorCode.NOTLOGIN;
		
		if((System.currentTimeMillis()-userinfo.getlastcalltime().getTime())>SysInfo.loginIndate)return ErrorCode.LOGINTIMEOUT;
		return ErrorCode.NORMAL;
	}

	
	

}